#lang racket

;; Question 3.a
(displayln "------------")
(displayln "")
(displayln "Question 3.a")
(define s '(y t r e w q ))
(reverse s)

;; Question 3.b
(displayln "------------")
(displayln "")
(displayln "Question 3.b")
(expt 2 5)

;; Question 3.c
(displayln "------------")
(displayln "")
(displayln "Question 3.c")
(string-join '("j'ai" "trouvé" "string-join"))

;;Question 4
(displayln "------------")
(displayln "")
(displayln "Question 4")
(define xx (/ 3 7))
(define yy xx)
(define toto(/ 3 7))

;; retourne vrai car xx et yy sont le même objet d'après la definition
;; dans le define
(eq? xx yy)

;; retourne faux car (/ 3 7) et (/ 3 7) sont deux objet différent
;; car il ne pointe pas sur la même adresse mémoire
(eq? (/ 3 7) (/ 3 7))

;; retourne vrai car (/ 3 7) et (/ 3 7) ont la même valeur
(eqv? (/ 3 7) (/ 3 7))

;; retourne vrai car 3 et 3 sont le même objet
(eq? 3 3)

;; retourne vrai car '(/ 3 7) et '(/ 3 7) est la même liste
(equal? '(/ 3 7) '(/ 3 7))

;; à vérifier
;; retourne faux car '(/ 3 7) et '(/ 3 7) ne sont pas eq?
(eqv? '(/ 3 7) '(/ 3 7))

;; retourne faux car (/ 3 7) et (/ 3 7) ne sont pas les même listes en mémoire
(eq? '(/ 3 7) '(/ 3 7))


(displayln "------------")
(displayln "")
(displayln "Question 5.b")
(define a 1)
(define b 0)
(define c '(1 2 3))
(define d c)
(if (= a b)
    'bonjour
    (if (eq? c d)
        'bonsoir
        (let ()
          (define x 3)
          (define y 5)
          (+ x y))))

;; Question 5.a
;; bonjour a=1, b=1, d=0
;; bonsoir a=1, b=0, d=c
;; 8 a=1, b=0, d=0

;; Question 5.b
(cond 
  [(= a b) 'bonjour]
  [(eq? c d) 'bonsoir]
  [(let()
     (define x 3)
     (define y 5)
     (+ x y))]
  )

;; Question 5.c
;; Le let est obligatoire car il permet d'être utilisé comme un test toujours vrai
;; et donc d'éxécuter les defines + le calcul

;; Question 5.d
(displayln "------------")
(displayln "")
(displayln "Question 5.d")
(let ()
  (define x 3)
  (define y 5)
  (* 9 11)
  (+ x y))
;; Retourne seulement la dernière expression éffectué

(displayln "")
(begin
  (define gx 3)
  (define gy 5)
  (* 9 11)
  (+ gx gy))
(displayln "")
(displayln "")
;; Retourne les deux calculs comme si ils étaient dans le root

;; Ici les deux sont équivalent, ils retournent la dernière valeur
;; mais le begin n'accepte pas de define
(if (= 1 1)
    (let ()
      (* 9 11)
      (+ gx gy))
    (/ gx gy))

(displayln "")
(if  (= 1 1)
     (begin
       (* 9 11)
       (+ gx gy))
     (/ gx gy))


(displayln "------------")
(displayln "")
(displayln "Question 6")

(cond [(zero? (+ 1 -4))
       (define z '(a b c d e))
       (drop z 2)]
      [(eqv? (/ 3 7) (/ 3 7))
       (displayln "quels sont les concepts que ce langage me forcent d'apprendre")]
      [else
       (print "c'est terminé")])

(if [zero? (+ 1 -0)]
    (let ()
      (define z '(a b c d e))
      (drop z 2)
      )
    (if [eqv? (/ 3 7) (/ 3 7)]
        (displayln "quels sont les concepts que ce langage me forcent d'apprendre")
        (print "c'est terminé")
        )
    )


(displayln "------------")
(displayln "")
(displayln "Question 7")

(displayln "")
(displayln "Définition f(x) :")
(define ff (λ(x)
            (+ (* 2 x) 3)
            )
  )
(print "f(1)=")
(ff 1)

(displayln "")
(displayln "Définition dist(a b) :")
(define dist (λ(a b)
               (sqrt (+ (expt a 2) (expt b 2)))
               )
  )

(print "dist(2 4)=")
(dist 2 4)


(displayln "")
(displayln "Définition g(x y) :")
(define fg (λ(gx gy) 
            (cond [(or (<= gx 0) (<= gy 0))
                   0]
                  [(and (< 5 (+ gx gy)) (< (+ gx gy) 10))
                   (dist gx gy)]
                  [else (expt 2.33 (+ gx gy))]
                  )
            )
  )
(print "g(2 4)=")(fg 2 4)
(print "g(-1 9)=")(fg -1 9)
(print "g(1 1)=")(fg 1 1)

(displayln "-------------")
(displayln "")
(displayln "Question 8.a")

(define x 5)
(define f (λ (x) (* x x)))

(displayln "Avec LET")
(let ()
  (define x 3)
  (define y (+ x 10))
  (* x y)
  (+ x y)
  )

(displayln "Sans LET")
((λ ()
   (define x 3)
   (define y (+ x 10))
   (+ x y)
   )
 )

(displayln "-------------")
(displayln "")
(displayln "Question 8.b")

(displayln "Avec LET")
(let ([x 3]
      [y (+ x 10)])
  (+ x y))

(displayln "Sans LET")
((λ (x y)(+ x y)) 3 (+ x 10))

(displayln "-------------")
(displayln "")
(displayln "Question 8.c")

(displayln "Avec LET")
(let* ([x 3]
       [y (+ x 10)])
  (* x y)
  (+ x y))

(displayln "Sans LET")
((λ (x)
    ((λ (y)(+ x y)) (+ x 10))
   ) 3)


(displayln "-------------")
(displayln "")
(displayln "Question 8.d")

(displayln "Avec LET")
(letrec ([g (λ (x) (/ (f x) 2))]
         [h (λ (x) (g (+ 3 x)))])
  (+ (g 4) (h 3)))

(displayln "Sans LET")
(define g (λ(x)(/ (f x) 2)))
(define h (λ(x)(g (+ 3 x))))
(+ (g 4) (h 3))